#include <kernel.h>

void
echo_server_proc(void *arg)
{
	 ekf_kprintf("i'm echo server!\n");
	 int s = lwip_socket(AF_INET, SOCK_STREAM, 0);

	 if (s < 0)
	 {
		  ekf_kprintf("SOCKET failed\n");
		  return;
	 }
	 
	 struct sockaddr_in sin;
	 sin.sin_len = sizeof(sin);
	 sin.sin_addr.s_addr = INADDR_ANY;
	 sin.sin_family = AF_INET;
	 sin.sin_port = htons(7);
	 memset(&sin.sin_zero, 0, sizeof(sin.sin_zero));

	 if (lwip_bind(s, (struct sockaddr *)&sin, sizeof(sin)))
	 {
		  ekf_kprintf("BIND failed\n");
		  return;
	 }

	 if (lwip_listen(s, 10))
	 {
		  ekf_kprintf("LISTEN failed\n");
		  return;
	 }

	 ekf_kprintf("listening....\n");
	 struct sockaddr_in clia;
	 u32_t clias;
	 while (1)
	 {
		  clias = sizeof(clia);
		  int cli = lwip_accept(s, (struct sockaddr *)&clia, &clias);
		  if (cli == -1)
		  {
			   break;
		  }
		  ekf_kprintf("accepted new client\n");
#define SIZE (1024 * 400)
		  char *c = (char *)ekf_alloc(SIZE);
		  int r;
		  // ekf_kprintf("!! %d to recv\n", timer_tick_get());
		  while ((r = lwip_recv(cli, c, SIZE, 0)) > 0)
		  {
			   // ekf_kprintf("!! %d %d\n", timer_tick_get(), r);
			   // ekf_kprintf("!! %d to send\n", timer_tick_get());
			   lwip_send(cli, c, r, 0);
			   // ekf_kprintf("!! %d to recv\n", timer_tick_get());
		  }
		  ekf_free(c);
		  lwip_close(cli);
		  ekf_kprintf("to accept\n");
	 }

	 ekf_kprintf("echo server exit\n");
}
